package com.huineta.business.modules.sys.service.impl;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.huineta.business.common.constant.TenantConstant;
import com.huineta.business.common.web.base.page.PageResponse;
import com.huineta.business.common.web.base.page.Pageable;
import com.huineta.business.modules.sys.domain.*;
import com.huineta.business.modules.sys.mapper.SysMenuMapper;
import com.huineta.business.modules.sys.mapper.SysTenantMapper;
import com.huineta.business.modules.sys.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huineta.business.modules.sys.param.SysTenantGiveRequest;
import com.huineta.business.modules.sys.param.SysTenantRequest;
import com.huineta.business.modules.sys.param.SysTenantSaveRequest;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;

@Service
public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant> implements ISysTenantService {

    @Resource
    private SysTenantMapper sysTenantMapper;

    @Resource
    private SysMenuMapper sysMenuMapper;

    @Resource
    private ISysUserService sysUserService;

    @Resource
    private ISysTenantMenuService sysTenantMenuService;

    @Resource
    private ISysRoleMenuService sysRoleMenuService;

    @Resource
    private ISysRoleService sysRoleService;

    @Resource
    private ISysUserRoleService sysUserRoleService;

    @Resource
    private ISysDeptService sysDeptService;

    @Resource
    private ISysPostService sysPostService;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Override
    public List<SysTenant> list(SysTenantRequest request) {
        return sysTenantMapper.selectTenant(request);
    }

    @Override
    public PageResponse<SysTenant> page(SysTenantRequest request) {
        return Pageable.of(request, (()-> sysTenantMapper.selectTenant(request)));
    }

    @Override
    public Boolean give(SysTenantGiveRequest request) {

        String tenantId = request.getTenantId();
        List<String> menuIds = request.getMenuIds();

        sysTenantMenuService.lambdaUpdate().eq(SysTenantMenu::getTenantId, tenantId).remove();

        for (String menuId :menuIds) {
            SysTenantMenu tenantMenu = new SysTenantMenu();
            tenantMenu.setMenuId(menuId);
            tenantMenu.setTenantId(tenantId);
            sysTenantMenuService.save(tenantMenu);
        }
        return true;
    }

    @Override
    @Transactional
    public Boolean save(SysTenantSaveRequest request) {

        String userId = IdWorker.getIdStr();
        String tenantId = IdWorker.getIdStr();
        String roleId = IdWorker.getIdStr();
        String deptId = IdWorker.getIdStr();
        String postId = IdWorker.getIdStr();
        SysTenant tenant = request.getTenant();
        sysTenantMapper.insert(tenant);

        SysPost sysPost = new SysPost();
        sysPost.setSort(0);
        sysPost.setId(postId);
        sysPost.setEnable(true);
        sysPost.setName(TenantConstant.DEFAULT_POST_NAME);
        sysPost.setCode(TenantConstant.DEFAULT_POST_CODE);
        sysPost.setTenantId(tenantId);
        sysPostService.save(sysPost);

        SysDept dept = new SysDept();
        dept.setSort(0);
        dept.setEnable(true);
        dept.setId(deptId);
        dept.setName(TenantConstant.DEFAULT_DEPT_NAME);
        dept.setParent(TenantConstant.DEFAULT_DEPT_PARENT);
        dept.setAddress(TenantConstant.DEFAULT_DEPT_ADDRESS);
        dept.setTenantId(tenantId);
        sysDeptService.save(dept);

        SysUser user = request.getUser();
        user.setId(userId);
        user.setEnable(true);
        user.setLocked(false);
        user.setDeptId(deptId);
        user.setTenantId(tenantId);
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        sysUserService.save(user);

        SysRole role = new SysRole();
        role.setId(roleId);
        role.setEnable(true);
        role.setTenantId(tenantId);
        role.setName(TenantConstant.DEFAULT_ROLE_NAME);
        role.setCode(TenantConstant.DEFAULT_ROLE_CODE);
        sysRoleService.save(role);

        SysUserRole userRole = new SysUserRole();
        userRole.setRoleId(roleId);
        userRole.setUserId(userId);
        userRole.setTenantId(tenantId);
        sysUserRoleService.save(userRole);

        List<String> menuIds = request.getMenuIds();

        for (String menuId: menuIds) {
            SysTenantMenu tenantMenu = new SysTenantMenu();
            tenantMenu.setTenantId(tenantId);
            tenantMenu.setMenuId(menuId);

            SysRoleMenu roleMenu = new SysRoleMenu();
            roleMenu.setRoleId(roleId);
            roleMenu.setMenuId(menuId);
            roleMenu.setTenantId(tenantId);

            sysRoleMenuService.save(roleMenu);
            sysTenantMenuService.save(tenantMenu);
        }
        return true;
    }

    @Override
    @Transactional
    public boolean removeById(Serializable id) {
        sysTenantMapper.deleteById(id);
        sysTenantMenuService.lambdaUpdate().eq(SysTenantMenu::getTenantId, id).remove();
        sysUserService.lambdaUpdate().eq(SysUser::getTenantId, id).remove();
        sysUserRoleService.lambdaUpdate().eq(SysUserRole::getTenantId, id).remove();
        sysRoleService.lambdaUpdate().eq(SysRole::getTenantId, id).remove();
        sysRoleMenuService.lambdaUpdate().eq(SysRoleMenu::getTenantId, id).remove();
        sysDeptService.lambdaUpdate().eq(SysDept::getTenantId, id).remove();
        sysPostService.lambdaUpdate().eq(SysPost::getTenantId, id).remove();
        return true;
    }

    @Override
    public boolean removeByIds(Collection<? extends Serializable> idList) {
        idList.forEach(this::removeById);
        return true;
    }

    @Override
    public List<SysMenu> permission(String tenantId) {
        return sysMenuMapper.selectMenuByTenantId(tenantId);
    }
}
